#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Attributes:
    __version__ (str): "0.0.1"
    __copyright__ (str): "Copyright (C) 2025 z"
    __license__ (str): "MIT"
    __author__ (str): "Z"
"""

import json

from flask import request

from wingman import db_enter, send, logger
from wingman.common.error import ErrorCode

class Elastalert:
    """
    接收ElasticSearch内经过ElastAlert规则筛选后的异常日志信息
    发送到钉钉/飞书及写入数据库
    """

    def __recomb_dict(self, dict_data, prefix="") -> dict:
        """
        重组字典数据,将嵌套字典扁平化处理
        Args:
            dict_data: 输入字典
            prefix: 键前缀
        Returns:
            content: 处理后的扁平化字典
        """

        if not isinstance(dict_data, dict):
            logger.critical(30000, "Input is not a dictionary", __name__)
            return dict_data

        content = {}
        for key, value in dict_data.items():
            if isinstance(value, dict):
                content.update(self.__recomb_dict(value, f"{prefix}{key}_"))
            elif isinstance(value, list):
                if key == "filebeat_ip":
                    content[key] = ", ".join(map(str, value))
                else:
                    for index, item in enumerate(value):
                        if isinstance(item, dict):
                            content.update(self.__recomb_dict(item, f"{prefix}{key}{index}_"))
            else:
                new_key = prefix + key
                if new_key in content:
                    existing_value = content[new_key]
                    if isinstance(existing_value, list):
                        existing_value.append(value)
                        content[new_key] = ", ".join(map(str, existing_value))
                    else:
                        content[new_key] = ", ".join([str(existing_value), str(value)])
                else:
                    content[new_key] = str(value).replace("'", "").replace("#", "")
        return content

    def __validate_json_data(self, json_data) -> dict:
        """验证 json_data 中的每个键值对,如果值为空,则将其替换为空字符串"""
        content = {key: ("None" if value is None or value == '' else value) for key, value in json_data.items()}
        return content

    def __check_request_data(self, request) -> dict:
        """检查并处理请求数据
        Args:
            request: Flask请求对象
        Returns:
            dict: 处理后的数据字典
        """
        data_methods = {
            'json': (lambda: request.get_json(), 'get_json'),
            'form': (lambda: request.form.to_dict(), 'form'),
            'data': (lambda: json.loads(request.get_data().decode('utf-8')), 'get_data'),
            'args': (lambda: request.args, 'args')
        }

        for method, (getter, method_name) in data_methods.items():
            if data := getter():
                check = self.__recomb_dict(data)
                check.update({
                    'source_client_ip': request.remote_addr,
                    'source_input_method': method_name
                })
                return self.__validate_json_data(check)
        return self.__validate_json_data({'error': 'No valid data found'})

    def elastalert_handler(func):
        """使用装饰器简化重复代码"""
        def wrapper(self):
            message = self.__check_request_data(request)
            function_name = func.__name__
            db_enter(message, function_name, "local")
            send(message, function_name)
            logger.info(ErrorCode.SUCCESS.value, message, function_name)
            return message
        wrapper.__name__ = func.__name__
        return wrapper

    # ----- ----- nginx ----- -----
    @elastalert_handler
    def get_elastalert_nginx(self): pass

    @elastalert_handler
    def get_elastalert_nginx_error(self): pass

    # # ----- ----- modsec ----- ----- 
    # def get_elastalert_modsec(self):

    # ----- ----- syslog ----- -----  
    @elastalert_handler
    def get_elastalert_syslog(self): pass

    # ----- ----- java ----- -----  
    @elastalert_handler
    def get_elastalert_java_info(self): pass

    @elastalert_handler
    def get_elastalert_java_error(self): pass

    # ----- ----- mysql ----- -----  
    @elastalert_handler
    def get_elastalert_mysql_slow(self): pass

    @elastalert_handler
    def get_elastalert_mysql_error(self): pass

    # # ----- ----- redis ----- ----- 
    # def get_elastalert_redis_error():

    # # ----- ----- php ----- ----- 
    # def get_elastalert_php_slow():
    # def get_elastalert_php_error():
    # def get_elastalert_writable():

    @elastalert_handler
    def fluendbit_systemd(self): pass
    @elastalert_handler
    def fluendbit_kubernetes(self): pass
    @elastalert_handler
    def fluendbit_logs(self): pass
    @elastalert_handler
    def fluendbit_docker(self): pass
